package com.bsoft.gol.hbs.message.messageHandle;

import com.alibaba.fastjson.JSONObject;
import com.bsoft.gol.hbs.utils.CommonUtils;
import com.bsoft.gol.hbs.utils.Constants;
import com.google.common.collect.Lists;
import com.security.cipher.sm.SM4Utils;
import ctd.spring.boot.annotation.SsdevReference;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.annotation.RpcService;
import ctd.util.context.Context;
import ctd.util.context.ContextUtils;
import hcn.base.Device;
import hcn.bean.MsgTemplateDTO;
import hcn.bean.PushMessageBean;
import hcn.bean.SendMsgDTO;
import com.bsoft.gol.mpi.model.Certificate;
import com.bsoft.gol.mpi.model.Person;
import com.bsoft.gol.mpi.model.Unique;
import com.bsoft.gol.mpi.provider.IMPIProvider;
import hcn.util.BaseResponse;
import hcn.service.base.sendMsg.IISendMsgService;
import hcn.service.base.sendMsg.MessageHandleService;
import hcn.util.IdentityTransformUtil;
import hcn.util.RpcUserToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import pcn.bean.consultation.MsgVariableQo;
import pcn.enums.RoleIdEnum;
import service.rpc.DeviceServiceIntf;
import service.rpc.OrganizationInfoIntf;
import service.rpc.PersonServiceIntf;

import java.util.*;

/**
 * @description: 消息处理服务的抽象实现, 对于该类中的实现子类中可以根据需求决定是否重写
 * @author: zhengcb10708
 * @create: 2020-09-28 13:42
 **/
@SsdevService("messageHandleService")
public  class AbstractMessageHandleServiceImpl implements MessageHandleService {
    private static Logger logger = LoggerFactory.getLogger(AbstractMessageHandleServiceImpl.class);
    @SsdevReference("gol-mpi.mpiProvider")
    private IMPIProvider mpiProvider;
    @Autowired
    private OrganizationInfoIntf organizationInfoIntf;
    @Autowired
    private PersonServiceIntf personServiceIntf;
    @Autowired
    private IISendMsgService sendMsgService ;
    @Autowired
    private DeviceServiceIntf deviceServiceIntf;


    @Override
    public boolean isMapping(String s) {
        return false;
    }

    /**
     * @Describe: 进行消息处理
     * @Param: [pushMessageBean]
     * @Return: BaseResponse
     * @Author: zhengcb10708
     * @Date: 2020/9/28 13:45
     */
    @RpcService
    @Override
    public BaseResponse messageHandle(PushMessageBean pushMessageBean) {
        BaseResponse baseResponse = new BaseResponse();
        //判断是否匹配，避免恶意调用
        if (isDefault()) {
            //得到所有需要推送的用户的发送设备
            this.getPushUserInfo(pushMessageBean);

            return doSendMessage(pushMessageBean);
        }
        return new BaseResponse();

    }

    /**
     * @Describe: 发送消息的默认实现，各实现类有需要可以重写此方法
     * @Param: [pushMessageBean]
     * @Return: BaseResponse
     * @Author: zhengcb10708
     * @Date: 2020/9/29 9:12
     */
    protected BaseResponse doSendMessage(PushMessageBean pushMessageBean) {
        //默认推送失败
        boolean pushFlag = false;
        BaseResponse baseResponse = new BaseResponse();

        SendMsgDTO sendMsgDTO = new SendMsgDTO();
        BeanUtils.copyProperties(pushMessageBean, sendMsgDTO);
        sendMsgDTO.setEventDate(new Date());
        JSONObject parameters = new JSONObject();
        List<MsgVariableQo> setMsgVariableList = new ArrayList<>();
        if(CommonUtils.isNotEmpty(sendMsgDTO.getMsgVariableMap())){
            for (Map.Entry<String, String> entry : sendMsgDTO.getMsgVariableMap().entrySet()) {
                MsgVariableQo MsgVariableQo = new MsgVariableQo();
                MsgVariableQo.setMsgVariableKey(entry.getKey());
                MsgVariableQo.setMsgVariableValue(entry.getValue());
                setMsgVariableList.add(MsgVariableQo);
                pushMessageBean.setMsgVariableList(setMsgVariableList);
            }
        }
        List<MsgVariableQo> msgVariableList = pushMessageBean.getMsgVariableList();
        if (msgVariableList != null && !msgVariableList.isEmpty()) {
            for (MsgVariableQo msgVariableRequest :
                    msgVariableList) {
                //把不带#的变量全部封装进
                if (msgVariableRequest.getMsgVariableKey().indexOf("#") < 0) {
                    parameters.put(msgVariableRequest.getMsgVariableKey(), msgVariableRequest.getMsgVariableValue
                            ());
                }
            }
        }
        sendMsgDTO.setParameters(parameters);
        MsgTemplateDTO msgTemplateDTO = new MsgTemplateDTO();
        msgTemplateDTO.setMsgVariableList(msgVariableList);
        msgTemplateDTO.setNotificateType(sendMsgDTO.getNotificateType());
        msgTemplateDTO.setSmsserviceType(sendMsgDTO.getSmsserviceType());
        msgTemplateDTO.setTenantId(sendMsgDTO.getTenantId());
        msgTemplateDTO.setTemplateCode(sendMsgDTO.getTemplateCode());
        baseResponse=sendMsgService.sendMsg(sendMsgDTO, msgTemplateDTO);
        return baseResponse;
    }

    /**
     * 得到所有需要推送的用户的发送设备
     * @param pushMessageBean
     */
    private void getPushUserInfo(PushMessageBean pushMessageBean ){
        logger.info("getPushUserInfo{} pushMessageBean {}"+pushMessageBean.toString());
        try{
            //用户类型：patient 患者/居民端   doctor:医生
            if(RoleIdEnum.PATIENT.title().equals(pushMessageBean.getRoleId())){
                List<Device> deviceAllList = Lists.newArrayList();
                List<Device> deviceList = null;
                Certificate certificate=null;
                String patientIdentityCardType=pushMessageBean.getPatientIdentityCardType();
                String patientIdentityCardNumber=pushMessageBean.getPatientIdentityCardNumber();
                Integer patientMedicalCardType= pushMessageBean.getPatientMedicalCardType();
                String patientMedicalCardNumber=pushMessageBean.getPatientMedicalCardNumber();

                String patientCode = pushMessageBean.getPatientCode();
                String hospitalCode = pushMessageBean.getHospitalCode();
                if(CommonUtils.isNotEmpty(patientIdentityCardNumber)||CommonUtils.isNotEmpty(patientMedicalCardNumber)){
                    if(CommonUtils.isNotEmpty(patientIdentityCardNumber)){
                        certificate = new Certificate(IdentityTransformUtil.huLianIdentityToHcn(pushMessageBean.getPatientIdentityCardType()),pushMessageBean.getPatientIdentityCardNumber(), "01");
                    }else{
                        certificate = new Certificate(IdentityTransformUtil.huLianIdentityToHcn(String.valueOf(pushMessageBean.getPatientMedicalCardType())),pushMessageBean.getPatientMedicalCardNumber(), "01");
                    }
                    logger.info("getPushUserInfo{} certificate {}="+certificate);
                    if(CommonUtils.isNotNull(certificate)){
                        Unique unique = mpiProvider.getUnique(certificate, Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
                        if(null!=unique){
                            String userId = unique.getUniqueId();
                            ContextUtils.put(Context.TENANT_ID, RpcUserToken.getTenantId());
                            deviceList = deviceServiceIntf.findOnLineDevices(SM4Utils.decryptData_ECB(userId), Constants.USER_ROLE_PATIENT);
                            ContextUtils.remove(Context.TENANT_ID);
                        }

                        if(CommonUtils.isEmpty(deviceList)){
                            deviceList = new ArrayList<>();
                        }
                        Person person = mpiProvider.getPersonByCertificate(certificate);
                        String mpiId="";
                        if(CommonUtils.isNotEmpty(person)){
                            mpiId=person.getMpiId();
                            List<String> masterMpiIds = personServiceIntf.findMasters(person.getMpiId());
                            if(CommonUtils.isNotEmpty(masterMpiIds)){
                                for (String masterMpiId : masterMpiIds) {
                                    Unique masterUnique = null;
                                    masterUnique = mpiProvider.getUnique(masterMpiId, Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
                                    if(null!= masterUnique){
                                        List<Device> patientUserDevice = deviceServiceIntf.findOnLineDevicesByUserId(SM4Utils.decryptData_ECB(masterUnique.getUniqueId()), RoleIdEnum.PATIENT.title(),RpcUserToken.getTenantId());
                                        if (patientUserDevice != null) {
                                            deviceList.addAll(patientUserDevice);
                                        }
                                    }

                                }
                            }
                        }
                        deviceAllList.addAll(deviceList);
                        if(CommonUtils.isNotEmpty(pushMessageBean.getDeviceList())){
                            deviceAllList.addAll(pushMessageBean.getDeviceList());
                        }
                        if(CommonUtils.isNotEmpty(deviceAllList)){
                            //发送设备去重处理
                            removeDuplicate(deviceAllList);
                            pushMessageBean.setDeviceList(deviceAllList);
                        }
                    }
                }else if(CommonUtils.isNotEmpty(patientCode)&&CommonUtils.isNotEmpty(hospitalCode)){
                    String orgId = organizationInfoIntf.getOrgIdByOrgCode(hospitalCode);
                    String mpiId ="";
                    logger.info("getPushUserInfo orgId {}  hospitalCode {}",orgId,hospitalCode);
                    if (orgId != null) {
                        mpiId = personServiceIntf.getMpiIdByPatientCode(patientCode, orgId);
                        logger.info("getPushUserInfo mpiId {}  ",mpiId);
                        if(mpiId != null) {
                            Person person = mpiProvider.getPerson(mpiId);
                            if(CommonUtils.isNotEmpty(person)){
                                certificate=person.getCertificate();
                                if(CommonUtils.isNotNull(certificate)){
                                    Unique unique = mpiProvider.getUnique(certificate, Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
                                    if(null!=unique){
                                        String userId = unique.getUniqueId();
                                        ContextUtils.put(Context.TENANT_ID,RpcUserToken.getTenantId());
                                        deviceList =deviceServiceIntf.findOnLineDevices(SM4Utils.decryptData_ECB(userId), Constants.USER_ROLE_PATIENT);
                                        ContextUtils.remove(Context.TENANT_ID);
                                    }

                                    if(CommonUtils.isEmpty(deviceList)){
                                        deviceList = new ArrayList<>();
                                    }
                                }
                                //查询被绑定的家庭成员设备
                                List<String> masterMpiIds = personServiceIntf.findMasters(person.getMpiId());
                                if(CommonUtils.isNotEmpty(masterMpiIds)){
                                    for (String masterMpiId : masterMpiIds) {
                                        Unique masterUnique = null;
                                        masterUnique = mpiProvider.getUnique(masterMpiId, Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
                                        if(null!= masterUnique){
                                            List<Device> patientUserDevice = deviceServiceIntf.findOnLineDevicesByUserId(SM4Utils.decryptData_ECB(masterUnique.getUniqueId()), RoleIdEnum.PATIENT.title(),RpcUserToken.getTenantId());
                                            if (patientUserDevice != null) {
                                                deviceList.addAll(patientUserDevice);
                                            }
                                        }
                                    }
                                }
                            }

                            deviceAllList.addAll(deviceList);
                            if(CommonUtils.isNotEmpty(pushMessageBean.getDeviceList())){
                                deviceAllList.addAll(pushMessageBean.getDeviceList());
                            }
                            if(CommonUtils.isNotEmpty(deviceAllList)){
                                //发送设备去重处理
                                removeDuplicate(deviceAllList);
                                pushMessageBean.setDeviceList(deviceAllList);
                            }
                        }
                    }
                }

            }
        }catch (Exception e){
           logger.error("excute getPushUserInfo 方法出错"+e.getMessage());
        }
    }

    //通过HashSet踢除重复元素
    public static List removeDuplicate(List list) {
        if(CommonUtils.isNotEmpty(list)){
            HashSet h = new HashSet(list);
            list.clear();
            list.addAll(h);
        }
        return list;
    }

    @Override
    public boolean isDefault() {
        return true;
    }
}
